package com.diandian.backend.kuaishou.life.exchange.service;

import com.alibaba.fastjson.JSON;
import com.diandian.backend.kuaishou.life.exchange.dto.KuaishouLifeTokenAddParamDTO;
import com.diandian.base.boot.starter.exception.DefaultException;
import com.diandian.kuaishou.life.boot.starter.constants.KuaiShouLifeConstant;
import com.diandian.kuaishou.life.boot.starter.dto.GetTokenByCodeRespDTO;
import com.diandian.kuaishou.life.boot.starter.service.KuaiShouLifeTokenBasicService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;

@Service
public class BusinessTokenGenerateService {

    private static final Logger logger = LoggerFactory.getLogger(BusinessTokenGenerateService.class);

    @Autowired
    private KuaiShouLifeTokenBasicService kuaiShouLifeTokenBasicService;

    @Autowired
    private BusinessKuaishouLifeTokenService businessKuaishouLifeTokenService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 接收店铺授权信息，并生成auth信息
     * @param code
     * @param state 格式必须为：userId-merchantId-appKey
     */
    public void generate(String localAppKey, String LocalAppSecret, String code, String state){

        // 参数校验
        if(code == null || "".equals(code)){
            throw new DefaultException("code不能为空");
        }
        if(state == null || "".equals(state)){
            throw new DefaultException("state不能为空");
        }

        // 参数解析
        String[] params = state.split("-");
        if(params.length != 3){
            throw new DefaultException("state格式不合法");
        }
        String userId = params[0];
        String merchantId = params[1];
        String appKey = params[2];
        if(!localAppKey.equals(appKey)){
            logger.info("当前配置的appKey {} 与线上Appkey {} 不匹配", localAppKey, appKey);
            throw new DefaultException("当前配置的appKey与线上Appkey不匹配");
        }

        // 调用接口获取token
        logger.info("执行调用接口获取token操作，参数：");
        GetTokenByCodeRespDTO tokenDTO = kuaiShouLifeTokenBasicService.getToken(localAppKey, LocalAppSecret, KuaiShouLifeConstant.PARAM_CODE, code);
        if(tokenDTO == null){
            logger.info("获取快手本地生活token异常，响应结果：{}", JSON.toJSONString(tokenDTO));
            throw new DefaultException("获取快手本地生活token异常");
        }
        if(!KuaiShouLifeConstant.PARAM_RESPONSE_SUCCESS_RESULT.equals(tokenDTO.getResult())){
            String message = tokenDTO.getError_msg();
            throw new DefaultException("获取快手本地生活token异常，异常信息：" + message);
        }

        logger.info("调用接口获取token结果：{}", JSON.toJSONString(tokenDTO));

        // 补充数据
        Long expiresIn = tokenDTO.getExpires_in();
        Date now = new Date();
        Date expriesDate = getAccessTokenExpiredDate(now, expiresIn);
        Date expiresDateRefreshToken = getRefreshTokenExpiredDate(now, KuaiShouLifeConstant.KUAI_SHOU_REFRESH_TOKEN_EXPIRE_DAY);
        tokenDTO.setExpired_date(expriesDate);
        tokenDTO.setExpiry_date_refresh_token(expiresDateRefreshToken);
        String dataJson = JSON.toJSONString(tokenDTO);

        // 删除原有的token记录
        businessKuaishouLifeTokenService.deleteByAppKeyAndMerchantId(appKey, merchantId);

        // 保存入库
        KuaishouLifeTokenAddParamDTO tokenAddParamDTO = new KuaishouLifeTokenAddParamDTO();
        tokenAddParamDTO.setUserId(userId);
        tokenAddParamDTO.setMerchantId(merchantId);
        tokenAddParamDTO.setAppKey(appKey);
        tokenAddParamDTO.setSourceTokenData(dataJson);
        tokenAddParamDTO.setAccessToken(tokenDTO.getAccess_token());
        tokenAddParamDTO.setRefreshToken(tokenDTO.getRefresh_token());
        tokenAddParamDTO.setOpenId(tokenDTO.getOpen_id());
        tokenAddParamDTO.setExpiresIn(expiresIn);
        tokenAddParamDTO.setExpiresDate(expriesDate);
        tokenAddParamDTO.setExpiresDateRefreshToken(expiresDateRefreshToken);
        tokenAddParamDTO.setScopes(tokenDTO.getScopes());

        logger.info("执行token入库操作，数据：{}", JSON.toJSONString(tokenAddParamDTO));
        businessKuaishouLifeTokenService.add(tokenAddParamDTO);

        // 保存到redis中
        String redisKey = KuaiShouLifeConstant.KUAI_SHOU_TOKEN_PRIFIX + appKey + ":" + merchantId;
        logger.info("执行token缓存操作，key:{}, 数据：{}", redisKey, dataJson);
        redisTemplate.opsForValue().set(redisKey, dataJson);

        logger.info("执行商家店铺首次token处理完成。");
    }

    /**
     * 计算access token过期时间
     * @return
     */
    private Date getAccessTokenExpiredDate(Date date, Long seconds){

        if(date == null || seconds == null){
            return null;
        }

        if(seconds.intValue() <= 3){
            return date;
        }

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, seconds.intValue() - 3); // 默认减掉10S作为交互占用时间
        return calendar.getTime();
    }

    /**
     * 计算refresh token过期时间
     * @return
     */
    private Date getRefreshTokenExpiredDate(Date date, int days){
        if(date == null){
            return null;
        }

        if(days <= 0){
            return date;
        }

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, days);
        return calendar.getTime();
    }
}
